{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9b2dac908ce82802",
   "metadata": {},
   "source": [
    "# CrewAI Markdown Validator\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "925e51b6",
   "metadata": {},
   "source": [
    "First let's install the required packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8c6c9f08b3228dcb",
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install -U crewai\n",
    "%pip install -U agentops\n",
    "%pip install -U python-dotenv\n",
    "%pip install -U pymarkdownlnt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "844b50cb",
   "metadata": {},
   "source": [
    "Then import them"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3930dc4c82f117b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "from crewai import Agent, Task, LLM\n",
    "from crewai.tools import tool\n",
    "import agentops\n",
    "import os\n",
    "from pathlib import Path\n",
    "from dotenv import load_dotenv\n",
    "from pymarkdown.api import PyMarkdownApi, PyMarkdownApiException"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e307923",
   "metadata": {},
   "source": [
    "Next, we'll set our API keys. There are several ways to do this, the code below is just the most foolproof way for the purposes of this notebook. It accounts for both users who use environment variables and those who just want to set the API Key here in this notebook.\n",
    "\n",
    "[Get an AgentOps API key](https://agentops.ai/settings/projects)\n",
    "\n",
    "1. Create an environment variable in a .env file or other method. By default, the AgentOps `init()` function will look for an environment variable named `AGENTOPS_API_KEY`. Or...\n",
    "\n",
    "2. Replace `<your_agentops_key>` below and pass in the optional `api_key` parameter to the AgentOps `init(api_key=...)` function. Remember not to commit your API key to a public repo!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e0e9166a",
   "metadata": {},
   "outputs": [],
   "source": [
    "load_dotenv()\n",
    "os.environ[\"AGENTOPS_API_KEY\"] = os.getenv(\"AGENTOPS_API_KEY\", \"your_api_key_here\")\n",
    "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\", \"your_openai_api_key_here\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a9283d4735b1226",
   "metadata": {},
   "source": [
    "The first step in any AgentOps integration is to call `agentops.init()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "701a00a193b93118",
   "metadata": {},
   "outputs": [],
   "source": [
    "agentops.init(tags=[\"markdown_validator\", \"agentops-example\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dba56fc45784bfa",
   "metadata": {},
   "source": [
    "Lets start by creating our markdown validator tool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cb2152baa314da66",
   "metadata": {},
   "outputs": [],
   "source": [
    "@tool(\"markdown_validation_tool\")\n",
    "def markdown_validation_tool(file_path: str) -> str:\n",
    "    \"\"\"\n",
    "    A tool to review files for markdown syntax errors.\n",
    "\n",
    "    Returns:\n",
    "    - validation_results: A list of validation results\n",
    "    and suggestions on how to fix them.\n",
    "    \"\"\"\n",
    "\n",
    "    print(\"\\n\\nValidating Markdown syntax...\\n\\n\" + file_path)\n",
    "\n",
    "    try:\n",
    "        if not (os.path.exists(file_path)):\n",
    "            return \"Could not validate file. The provided file path does not exist.\"\n",
    "\n",
    "        scan_result = PyMarkdownApi().scan_path(file_path.rstrip().lstrip())\n",
    "        results = str(scan_result)\n",
    "        return results  # Return the reviewed document\n",
    "    except PyMarkdownApiException as this_exception:\n",
    "        print(f\"API Exception: {this_exception}\", file=sys.stderr)\n",
    "        return f\"API Exception: {str(this_exception)}\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bae481e07b5fadc2",
   "metadata": {},
   "source": [
    "Lets create our Agent with CrewAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3c9ca4fa0540a142",
   "metadata": {},
   "outputs": [],
   "source": [
    "default_llm = LLM(\n",
    "    model=\"openai/gpt-4o-mini\",\n",
    "    max_tokens=4000,\n",
    ")\n",
    "\n",
    "general_agent = Agent(\n",
    "    role=\"Requirements Manager\",\n",
    "    goal=\"\"\"Provide a detailed list of the markdown \n",
    "                            linting results. Give a summary with actionable \n",
    "                            tasks to address the validation results. Write your \n",
    "                            response as if you were handing it to a developer \n",
    "                            to fix the issues.\n",
    "                            DO NOT provide examples of how to fix the issues or\n",
    "                            recommend other tools to use.\"\"\",\n",
    "    backstory=\"\"\"You are an expert business analyst \n",
    "\t\t\t\t\tand software QA specialist. You provide high quality, \n",
    "                    thorough, insightful and actionable feedback via \n",
    "                    detailed list of changes and actionable tasks.\"\"\",\n",
    "    allow_delegation=False,\n",
    "    verbose=True,\n",
    "    tools=[markdown_validation_tool],\n",
    "    llm=default_llm,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7940a03ceb4a55de",
   "metadata": {},
   "source": [
    "Now lets create the task for our agent to complete"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "28b4abd52ff9bf86",
   "metadata": {},
   "outputs": [],
   "source": [
    "filename = f\"{Path(os.getcwd()).parent.parent.absolute()}/README.md\"\n",
    "\n",
    "syntax_review_task = Task(\n",
    "    description=f\"\"\"\n",
    "        Use the markdown_validation_tool to review \n",
    "        the file(s) at this path: {filename}\n",
    "        \n",
    "        Be sure to pass only the file path to the markdown_validation_tool.\n",
    "        Use the following format to call the markdown_validation_tool:\n",
    "        Do I need to use a tool? Yes\n",
    "        Action: markdown_validation_tool\n",
    "        Action Input: {filename}\n",
    "\n",
    "        Get the validation results from the tool \n",
    "        and then summarize it into a list of changes\n",
    "        the developer should make to the document.\n",
    "        DO NOT recommend ways to update the document.\n",
    "        DO NOT change any of the content of the document or\n",
    "        add content to it. It is critical to your task to\n",
    "        only respond with a list of changes.\n",
    "        \n",
    "        If you already know the answer or if you do not need \n",
    "        to use a tool, return it as your Final Answer.\"\"\",\n",
    "    agent=general_agent,\n",
    "    expected_output=\"\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7283562a262056d5",
   "metadata": {},
   "source": [
    "Now lets run our task!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d5c5f01bee50b92a",
   "metadata": {},
   "outputs": [],
   "source": [
    "syntax_review_task.execute_sync()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "agentops (3.11.11)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
